import { _decorator, Component, Node, Prefab, instantiate, Vec3, CCInteger, find, Vec2 } from 'cc';
const { ccclass, property } = _decorator;

// 2D区块信息接口（仅包含X/Y轴）
interface Chunk2DInfo {
    x: number; // 区块网格X坐标（如-1, 0, 1）
    y: number; // 区块网格Y坐标
    node: Node; // 区块节点
}

@ccclass('InfiniteMap2D')
export class InfiniteMap2D extends Component {
    @property({ type: Prefab, tooltip: "2D地图区块预制体（确保能无缝拼接）" })
    chunkPrefabs: Prefab[] = [];

    @property({ type: CCInteger, tooltip: "单个区块的尺寸（像素/单位）" })
    chunkSize: number = 500; // 2D游戏常用500x500单位的区块

    @property({ type: CCInteger, tooltip: "加载范围（以玩家为中心，向X/Y方向各加载多少区块）" })
    loadRange: number = 2; // 建议2-3，避免加载过多区块影响性能

    @property({ type: Node, tooltip: "玩家节点" })
    player: Node = null;

    // 已加载的区块（用"x,y"作为唯一键）
    private loadedChunks: { [key: string]: Chunk2DInfo } = {};
    
    // 玩家当前所在的区块网格坐标
    private currentChunkX: number = 0;
    private currentChunkY: number = 0;

    onLoad() {
        if (!this.player) {
            this.player = find('Player');
        }
    }

    start() {
        if (this.player) {
            // 初始化玩家所在区块并加载周围区块
            this.updatePlayerChunkPos();
            this.loadChunksInRange();
        } else {
            console.error("请指定玩家节点！");
        }
    }

    update(deltaTime: number) {
        if (!this.player) return;

        // 检测玩家是否进入新的区块
        const newChunkX = Math.floor(this.player.position.x / this.chunkSize);
        const newChunkY = Math.floor(this.player.position.y / this.chunkSize);

        if (newChunkX !== this.currentChunkX || newChunkY !== this.currentChunkY) {
            this.currentChunkX = newChunkX;
            this.currentChunkY = newChunkY;
            this.updateChunks(); // 刷新区块加载状态
        }
    }

    // 更新玩家当前所在的区块坐标
    private updatePlayerChunkPos() {
        this.currentChunkX = Math.floor(this.player.position.x / this.chunkSize);
        this.currentChunkY = Math.floor(this.player.position.y / this.chunkSize);
    }

    // 刷新区块：卸载远处区块，加载新区块
    private updateChunks() {
        this.unloadDistantChunks();
        this.loadChunksInRange();
    }

    // 加载玩家周围范围内的所有区块
    private loadChunksInRange() {
        // 遍历加载范围（X从左到右，Y从下到上）
        for (let x = -this.loadRange; x <= this.loadRange; x++) {
            for (let y = -this.loadRange; y <= this.loadRange; y++) {
                const chunkX = this.currentChunkX + x;
                const chunkY = this.currentChunkY + y;
                this.loadChunk(chunkX, chunkY);
            }
        }
    }

    // 加载指定网格坐标的区块
    private loadChunk(chunkX: number, chunkY: number) {
        const key = this.getChunkKey(chunkX, chunkY);
        if (this.loadedChunks[key]) return; // 已加载则跳过

        // 随机选择一个区块预制体（增加地图多样性）
        if (this.chunkPrefabs.length === 0) {
            console.error("请添加区块预制体！");
            return;
        }
        const randomPrefab = this.chunkPrefabs[Math.floor(Math.random() * this.chunkPrefabs.length)];
        const chunkNode = instantiate(randomPrefab);

        // 设置区块位置（2D场景中Z轴固定为0）
        chunkNode.setParent(this.node);
        chunkNode.position = new Vec3(
            chunkX * this.chunkSize, // X轴位置
            chunkY * this.chunkSize, // Y轴位置
            0 // 2D无需Z轴，固定为0
        );

        // 存储区块信息
        this.loadedChunks[key] = {
            x: chunkX,
            y: chunkY,
            node: chunkNode
        };

        // 在区块中生成敌人和道具（割草游戏核心逻辑）
        this.spawnEnemiesAndItems(chunkNode, chunkX, chunkY);
    }

    // 卸载超出加载范围的区块
    private unloadDistantChunks() {
        const keysToRemove: string[] = [];

        for (const key in this.loadedChunks) {
            const chunk = this.loadedChunks[key];
            // 计算区块与玩家当前区块的距离
            const distanceX = Math.abs(chunk.x - this.currentChunkX);
            const distanceY = Math.abs(chunk.y - this.currentChunkY);

            // 超出加载范围则标记卸载
            if (distanceX > this.loadRange || distanceY > this.loadRange) {
                keysToRemove.push(key);
            }
        }

        // 执行卸载
        keysToRemove.forEach(key => {
            const chunk = this.loadedChunks[key];
            chunk.node.destroy(); // 销毁区块节点
            delete this.loadedChunks[key]; // 从缓存中移除
        });
    }

    // 在区块中生成敌人和道具（需根据游戏逻辑实现）
    private spawnEnemiesAndItems(chunkNode: Node, chunkX: number, chunkY: number) {
        // 示例：根据区块坐标生成不同密度的敌人
        const enemyDensity = this.calculateEnemyDensity(chunkX, chunkY);
        
        // 实际项目中，这里会调用敌人管理器生成敌人
        // 例如：
        // const enemyManager = find('EnemyManager').getComponent(EnemyManager2D);
        // enemyManager.spawnEnemiesInArea(
        //     new Vec2(chunkX * this.chunkSize, chunkY * this.chunkSize), // 区块左上角
        //     new Vec2(this.chunkSize, this.chunkSize), // 区块大小
        //     enemyDensity // 敌人数量
        // );
    }

    // 根据区块坐标计算敌人密度（可用于实现难度递增）
    private calculateEnemyDensity(chunkX: number, chunkY: number): number {
        // 离初始区块越远，敌人密度越高（割草游戏常用逻辑）
        const distanceFromOrigin = Math.sqrt(chunkX * chunkX + chunkY * chunkY);
        return Math.max(2, Math.floor(distanceFromOrigin / 2)); // 基础2个，随距离递增
    }

    // 生成区块的唯一标识（X,Y拼接字符串）
    private getChunkKey(x: number, y: number): string {
        return `${x},${y}`;
    }

    // 外部获取区块尺寸（方便其他系统使用，如碰撞检测）
    getChunkSize(): number {
        return this.chunkSize;
    }
}
